﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using OConf.Entity;
using System;
using System.Collections.Generic;
using System.Linq;

namespace OConf.Service
{
    public class CNameSpaceService
	{
		private readonly IConfiguration _configuration;

		public CNameSpaceService(IConfiguration configuration)
		{
            _configuration = configuration;
		}

        public bool IsExist(string id)
        {
            bool isExists = false;
            using (MyDBContext db = new MyDBContext(_configuration))
            {
                isExists = db.CNameSpace.Any(w => w.ID == id);
            }
            return isExists;
        }

        /// <summary>
        /// 相同项目下是否存在同样的命名空间
        /// </summary>
        /// <param name="nameSpace"></param>
        /// <param name="proID"></param>
        /// <returns></returns>
        public bool IsExistByNameSpaceProID(string nameSpace, string proID)
		{
			bool isExists = false;
            using (MyDBContext db = new MyDBContext(_configuration))
			{
                isExists = db.CNameSpace.Any(w => w.NameSpace == nameSpace && w.ProjectID == proID);
            }
			return isExists;
        }

		public CNameSpaceEntity FindEntity(string id)
		{
			CNameSpaceEntity entity = null;
            using (MyDBContext db = new MyDBContext(_configuration))
			{
                entity = db.CNameSpace.Where(w => w.ID == id).FirstOrDefault();
            }
			return entity;
        }

		public bool AddEntity(CNameSpaceEntity entity)
		{
			bool isSuccess = false;
            using (MyDBContext db = new MyDBContext(_configuration))
            {
                db.CNameSpace.Add(entity);
                isSuccess = db.SaveChanges() > 0;
            }
            return isSuccess;
		}

		public bool Update(CNameSpaceEntity entity)
		{
            bool isSuccess = false;
            using (MyDBContext db = new MyDBContext(_configuration))
            {
                db.Update(entity);
                isSuccess = db.SaveChanges() > 0;
            }
            return isSuccess;
		}

        /// <summary>
        /// 修改发布状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isPublish"></param>
        /// <returns></returns>
        public bool UpdateIsPublish(string id, bool isPublish)
        {
            bool isSuccess = false;
            using (MyDBContext db = new MyDBContext(_configuration))
            {
                CNameSpaceEntity entity = new CNameSpaceEntity()
                {
                    ID = id,
                    IsPublish = isPublish
                };
                db.CNameSpace.Attach(entity);
                db.CNameSpace.Entry(entity).Property(p => p.IsPublish).IsModified = true;
                isSuccess = db.SaveChanges() > 0;
            }
            return isSuccess;
        }

        public void PublishNameSpaceByTran(string nameSpaceId, string projectId, long now, VersionsEntity version)
        {
            int rows = 0;
            using (MyDBContext db = new MyDBContext(_configuration))
            {
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {
                        //修改NameSpace发布状态为已发布
                        CNameSpaceEntity entity = new CNameSpaceEntity()
                        {
                            ID = nameSpaceId,
                            IsPublish = true
                        };
                        db.CNameSpace.Attach(entity);
                        db.Entry(entity).Property(p => p.IsPublish).IsModified = true;
                        if (db.SaveChanges() <= 0)
                        {
                            throw new Exception("修改NameSpace发布状态为已发布失败");
                        }

                        //修改ProjectInfo最后发布时间
                        ProjectInfoEntity projectInfo = new ProjectInfoEntity()
                        {
                            ID = projectId,
                            LastPublishTime = now
                        };
                        db.ProjectInfo.Attach(projectInfo);
                        db.Entry(projectInfo).Property(p => p.LastPublishTime).IsModified = true;
                        if (db.SaveChanges() <= 0)
                        {
                            throw new Exception("修改ProjectInfo最后发布时间失败");
                        }

                        //命名空间下的配置信息，新增和更改状态的配置信息状态更新为“已发布”
                        db.ConfigInfo.Where(w => w.NameSpaceID == nameSpaceId && (w.State == (int)ConfigInfoState.改 || w.State == (int)ConfigInfoState.增))
                            .ExecuteUpdate(x => x.SetProperty(p => p.State, (int)ConfigInfoState.已发布));

                        //命名空间下，删除状态的配置信息进行删除
                        db.ConfigInfo.Where(w => w.NameSpaceID == nameSpaceId && w.State == (int)ConfigInfoState.删)
                            .ExecuteDelete();

                        //生成版本信息
                        db.Versions.Add(version);
                        if (db.SaveChanges() <= 0)
                        {
                            throw new Exception("生成版本信息失败");
                        }

                        //生成配置信息历史
                        List<ConfigInfoEntity> configs = db.ConfigInfo.Where(w => w.NameSpaceID == nameSpaceId && w.State == (int)ConfigInfoState.已发布).ToList();
                        var configInfoHistorys = configs.Select(w => new ConfigInfoHistoryEntity()
                        {
                            ID = Guid.NewGuid().ToString("N"),
                            VersionID = version.ID,
                            ConfigKey = w.ConfigKey,
                            ConfigValue = w.ConfigValue,
                            ConfigDescription = w.ConfigDescription
                        }).ToList();
                        db.ConfigInfoHistory.AddRange(configInfoHistorys);
                        db.SaveChanges();

                        tran.Commit();
                    }
                    catch
                    {
                        tran.Rollback();
                        throw;
                    }
                }
            }
        }

		public List<CNameSpaceEntity> GetList(string proID)
		{
			List<CNameSpaceEntity> result = new List<CNameSpaceEntity>();
            using (MyDBContext db = new MyDBContext(_configuration))
            {
                result = db.CNameSpace.Where(w => w.ProjectID == proID)
                    .OrderByDescending(w => w.Createtime).ToList();
            }
            return result;
		}

		public List<CNameSpaceEntity> GetList(string proID, bool isPublish)
		{
            List<CNameSpaceEntity> result = new List<CNameSpaceEntity>();
            using (MyDBContext db = new MyDBContext(_configuration))
            {
                result = db.CNameSpace.Where(w => w.ProjectID == proID && w.IsPublish == isPublish)
                    .OrderByDescending(w => w.Createtime).ToList();
            }
            return result;
		}

		/// <summary>
		/// 使用事务删除命名空间和下级配置信息
		/// </summary>
		/// <param name="id"></param>
		public void DeleteByTran(string id)
		{
            using (MyDBContext db = new MyDBContext(_configuration))
			{
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {
                        CNameSpaceEntity entity = new CNameSpaceEntity()
                        {
                            ID = id
                        };
                        db.CNameSpace.Remove(entity);
                        db.SaveChanges();

                        db.ConfigInfo.Where(w => w.NameSpaceID == id)
                            .ExecuteDelete();

                        tran.Commit();
                    }
                    catch
                    {
                        tran.Rollback();
                        throw;
                    }
                }
            }
		}
	}
}
